package com.dream.base.web.job.impl;

import java.io.InputStreamReader;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dream.base.web.job.InitialDatabaseService;
import com.dream.dao.base.AppCodeDAO;
import com.dream.dao.base.AppOrgDAO;
import com.dream.dao.base.AppGroupDAO;
import com.dream.dao.base.AppGroupResourceDAO;
import com.dream.dao.base.AppPositionDAO;
import com.dream.dao.base.AppResourceDAO;
import com.dream.dao.base.AppUserDAO;
import com.dream.dao.base.AppUserGroupDAO;
import com.dream.dao.master.ProductCategoryDAO;
import com.dream.model.app.AppAbstractUser.UserStatus;
import com.dream.model.app.AppCode;
import com.dream.model.app.AppGroup;
import com.dream.model.app.AppGroupResource;
import com.dream.model.app.AppGroupResource.AppGroupResourcePK;
import com.dream.model.app.AppOrg;
import com.dream.model.app.AppPosition;
import com.dream.model.app.AppResource;
import com.dream.model.app.AppUser;
import com.dream.model.app.AppUserGroup;
import com.dream.model.master.ProductCategory;
import com.dream.utils.io.FileIOUtils;
import com.dream.utils.log.DreamLogUtils;
import com.dream.vo.app.AppCodeVO;
import com.dream.vo.base.Constants;
import com.thoughtworks.xstream.XStream;

@Service("InitialDatabaseService")   
public class InitialDatabaseServiceImpl implements InitialDatabaseService   {
	
	@Autowired
	private AppCodeDAO appCodeDAO;

	@Autowired
	private AppUserDAO appUserDAO;

	@Autowired
	private AppGroupDAO appGroupDAO;

	@Autowired
	private AppOrgDAO appOrgDAO;

	@Autowired
	private AppPositionDAO appPositionDAO;

	@Autowired
	private AppUserGroupDAO appUserGroupDAO;

	@Autowired
	private AppResourceDAO appResourceDAO;

	@Autowired
	private AppGroupResourceDAO appGroupResourceDAO;
	
	@Autowired
	private ProductCategoryDAO productCategoryDAO;
	
	@Transactional
	public void init() {
		initProductCat();
		initAppCode();
		initAdmin();
		initGroup();
		initAdminGroup();
		initResource();
		//initPosition();
		initOrg();
	}


	private String encoding = "utf-8";
	
	@Transactional
	public void initProductCat() {
		
		ProductCategory root = productCategoryDAO.getRoot();
		if(root == null){
			ProductCategory cat = new ProductCategory();
			cat.setName("产品分类");
			cat.setParentId(-1L);
			cat.setLevel(0);
			cat.setCreateTime(new Date());
			cat.setUpdateTime(new Date());
			productCategoryDAO.save(cat);
		}
		
		
	}
	
	@Transactional
	public void initAppCode() {

		XStream xs = new XStream();
		InputStreamReader in = null;
		try {
			in = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("initdata/app_code.xml"),
					encoding);

			@SuppressWarnings("unchecked")
			List<AppCode> codes = (List<AppCode>) xs.fromXML(in);

			if (CollectionUtils.isNotEmpty(codes)) {
				for (AppCode code : codes) {
					
					AppCodeVO vo = new AppCodeVO();
					vo.setName(code.getName());
					if (!appCodeDAO.existed(vo)) {
						code.setCreateUser(Constants.ADMIN_ID);
						code.setCreateTime(new Date());
						code.setDeleted(false);
						appCodeDAO.save(code);
					}
				}
			}

		} catch (Exception e) {
			DreamLogUtils.error(this, "initCode", "init admin data occured exception", e);
			throw new RuntimeException(e);
		} finally {
			FileIOUtils.close(in);
		}

	}
	
	@Transactional
	public void initAdmin() {

		XStream xs = new XStream();
		InputStreamReader in = null;
		try {
			in = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("initdata/app_admin.xml"),
					encoding);

			@SuppressWarnings("unchecked")
			List<AppUser> admins = (List<AppUser>) xs.fromXML(in);

			if (CollectionUtils.isNotEmpty(admins)) {
				for (AppUser admin : admins) {

					if (!appUserDAO.isExist(admin.getId())) {

						admin.setStatus(UserStatus.active);
						admin.setCreateUser(Constants.ADMIN_ID);
						admin.setCreateTime(new Date());
						admin.setDisplay(false);
						appUserDAO.save(admin);
					}
				}
			}

		} catch (Exception e) {
			DreamLogUtils.error(this, "initCode", "init admin data occured exception", e);
			throw new RuntimeException(e);
		} finally {
			FileIOUtils.close(in);
		}

	}
	@Transactional
	public void initGroup() {

		XStream xs = new XStream();
		InputStreamReader in = null;

		try {
			in = new InputStreamReader(this.getClass().getClassLoader()
							.getResourceAsStream("initdata/app_group.xml"), encoding);

			@SuppressWarnings("unchecked")
			List<AppGroup> groups = (List<AppGroup>) xs.fromXML(in);

			if (CollectionUtils.isNotEmpty(groups)) {
				for (AppGroup group : groups) {
					if (!appGroupDAO.isExist(group.getId())) {
						group.setCreateTime(new Date());
						group.setCreateUser(Constants.ADMIN_ID);
						group.setDeleted(false);
						appGroupDAO.save(group);
					}
				}
			}

		} catch (Exception e) {
			DreamLogUtils.error(this, "initGroup", "init group data occured exception", e);
			throw new RuntimeException(e);
		} finally {
			FileIOUtils.close(in);
		}
	}
	@Transactional
	public void initAdminGroup() {

		XStream xs = new XStream();
		InputStreamReader in = null;

		try {
			in = new InputStreamReader(this.getClass().getClassLoader()
					.getResourceAsStream("initdata/app_admin_group.xml"), encoding);

			@SuppressWarnings("unchecked")
			List<AppUserGroup> userGroups = (List<AppUserGroup>) xs.fromXML(in);

			if (CollectionUtils.isNotEmpty(userGroups)) {
				for (AppUserGroup ur : userGroups) {
					if (!appUserGroupDAO.existed(ur.getUserId(), ur.getGroupId())) {
						ur.setDeleted(false);
						ur.setCreateTime(new Date());
						ur.setCreateUser(Constants.ADMIN_ID);
						appUserGroupDAO.save(ur);
					}
				}
			}

		} catch (Exception e) {
			DreamLogUtils.error(this, "initGroup", "init group data occured exception", e);
			throw new RuntimeException(e);
		} finally {
			FileIOUtils.close(in);
		}
	}
	@Transactional
	public void initResource() {

		XStream xs = new XStream();

		InputStreamReader in = null;
		try {
			in = new InputStreamReader(this.getClass().getClassLoader().
					getResourceAsStream("initdata/app_resource.xml"), encoding);

			@SuppressWarnings("unchecked")
			List<AppResource> resources = (List<AppResource>) xs.fromXML(in);
			AppGroup adminGroup = appGroupDAO.getByName("admin");
			if (CollectionUtils.isNotEmpty(resources)) {
				for (AppResource ar : resources) {
					Long id = ar.getId();
					if (!appResourceDAO.existed(ar.getUri())) {
						ar.setDeleted(false);
						ar.setNeedCheck(true);
						ar.setCreateTime(new Date());
						ar.setCreateUser(Constants.ADMIN_ID);
						id = (Long) appResourceDAO.save(ar);
						if (!appGroupResourceDAO.existed(adminGroup.getId(), id)) {
							AppGroupResource gr = new AppGroupResource();
							AppGroupResourcePK pk = new AppGroupResourcePK();
							pk.setGroupId(adminGroup.getId());
							pk.setResourceId(id);
							gr.setId(pk);
							appGroupResourceDAO.save(gr);
						}
					}
					
				}
			}

		} catch (Exception e) {
			DreamLogUtils.error(this, "initGroup", "init group data occured exception", e);
			throw new RuntimeException(e);
		} finally {
			FileIOUtils.close(in);
		}
	}
	@Transactional
	public void initOrg() {

		AppOrg root = appOrgDAO.getRoot();
		if(root == null){
			AppOrg cat = new AppOrg();
			cat.setName("组织结构");
			cat.setParentId(-1L);
			cat.setLevel(0);
			cat.setCreateTime(new Date());
			cat.setUpdateTime(new Date());
			appOrgDAO.save(cat);
		}
	}
	@Transactional
	public void initPosition() {

		XStream xs = new XStream();
		InputStreamReader in = null;

		try {
			in = new InputStreamReader(this.getClass().getClassLoader()
							.getResourceAsStream("initdata/app_position.xml"), encoding);

			@SuppressWarnings("unchecked")
			List<AppPosition> poss = (List<AppPosition>) xs.fromXML(in);

			if (CollectionUtils.isNotEmpty(poss)) {
				for (AppPosition pos : poss) {
					if (!appPositionDAO.isExist(pos.getId())) {
						pos.setCreateTime(new Date());
						pos.setCreateUser(Constants.ADMIN_ID);
						pos.setDeleted(false);
						appPositionDAO.save(pos);
					}
				}
			}

		} catch (Exception e) {
			DreamLogUtils.error(this, "initPosition", "init position data occured exception", e);
			throw new RuntimeException(e);
		} finally {
			FileIOUtils.close(in);
		}
	}
	
}
